package com.jz.dsq.specification;

import cn.hutool.core.util.StrUtil;
import com.jz.dsq.utils.DsqUtil;
import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.*;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author zhangliang
 */
public interface AbstractSpecification<T> extends Specification<T>, Serializable {

    String DOT = ".";

    /**
     * 生成最后一个字段
     *
     * @param property
     * @return {@link String}
     * @author zhangliang
     */
    default String getProperty(String property, Root<T> root) {
        DsqUtil.validateFieldKey(property,root.getJavaType());
        if (property.contains(DOT)) {
            return StrUtil.split(property, DOT)[1];
        }
        return property;
    }

    /**
     * 支持 ManyToOne 和 OneToMany 查询
     * @param property
     * @return {@link String}
     * @author zhangliang
     */
    default From getRoot(String property, Root<T> root) {
        if (property.contains(DOT)) {
            String[] propertyArr = StrUtil.split(property, DOT);
            // OneToMany
            String joinProperty = propertyArr[0];
            Class<?> clazz = root.get(joinProperty).getJavaType();
            if (clazz.equals(Set.class)) {
                return root.joinSet(joinProperty, JoinType.LEFT);
            } else if (clazz.equals(List.class)) {
                return root.joinList(joinProperty, JoinType.LEFT);
            } else if (clazz.equals(Map.class)) {
                return root.joinMap(joinProperty, JoinType.LEFT);
            } else {
                // ManyToOne
                return root.join(joinProperty, JoinType.LEFT);
            }
        }
        return root;
    }

}
